#include <iostream>         // 标准输入输出流
#include <thread>           // 多线程支持库
#include <future>           // 异步操作库（future/promise/async）
#include <chrono>           // 时间处理库

// 模拟耗时操作的加法函数
int Add(int num1, int num2) 
{
    std::cout << "加法开始--第一阶段\n";
    std::this_thread::sleep_for(std::chrono::seconds(5));  // 模拟5秒耗时操作
    std::cout << "加法完成--第二阶段\n";
    return num1 + num2;  // 返回计算结果
}

int main() 
{
   // 一、std::launch::deferred（延迟执行）
   /*
   1、异步任务不会立即启动，而是延迟到调用 future.get() 或 future.wait() 时执行。
   2、任务在调用 get() 的线程中同步执行（不创建新线程）。
   3、如果没有调用 get() 或 wait()，任务永远不会执行。
   std::cout << "--------主线程开始----------\n";
   */

   // 二、std::launch::async（异步执行）
   /*
   1、立即创建新线程执行任务，任务异步运行。
   2、即使不调用 get()，任务也会在后台执行。
   3、调用 get() 时，若任务未完成，则阻塞等待结果。
   */
    
   // 使用async启动异步任务
   // 参数说明：
   //   std::launch::async - 立即创建新线程执行任务
   //   Add - 要执行的函数
   //   11, 22 - 函数参数
   std::future<int> result = std::async(std::launch::async, Add, 11, 22);
    
   // 主线程继续执行（此时异步任务已在后台运行）
   std::this_thread::sleep_for(std::chrono::seconds(1));  // 主线程休眠1秒
   std::cout << "--------主线程继续执行----------\n";
    
   // 获取异步任务结果（若未完成则阻塞等待）
   int sum = result.get();  // 此处会等待Add函数执行完成
   std::cout << "--------结果已获取----------\n";
    
   // 输出计算结果
   std::cout << "计算结果：" << sum << std::endl;  // 预期输出33
    
   return 0;
}

/*
执行时序分析：
1. 输出"--------主线程开始----------"
2. 启动异步任务，立即输出"加法开始--第一阶段"
3. 主线程休眠1秒（此时异步任务仍在执行）
4. 输出"--------主线程继续执行----------"
5. 调用result.get()开始等待：
   - 若异步任务未完成（约需再等待4秒）
   - 待异步任务完成，输出"加法完成--第二阶段"
6. 继续执行后续代码，输出结果信息

注意：
1. future.get()只能调用一次，多次调用会抛出异常
2. 使用std::launch::async策略时：
   - 保证创建独立线程执行
   - 若资源不足可能抛出std::system_error
3. 对比std::launch::deferred策略：
   - 延迟执行，直到调用get()时才在当前线程执行
   - 不会创建新线程
*/